// Copyright 2017 Baidu Inc. All Rights Reserved.
// Author: Su Hao (suhao@baidu.com)
//
// Description: The debug module.

#include <stdarg.h>
#include "baidu_ca_internal.h"

#define DEBUG_BUF_SIZE  (512)

typedef struct _baidu_ca_debug_s {
    bca_context     context;
    bca_debug_f     f_debug;
} bca_debug_t;

BCA_LOC_IMPL bca_debug_t s_bca_debug = {NULL};

BCA_EXT_IMPL void baidu_ca_debug_init(bca_context ctx, bca_debug_f f_debug) {
    s_bca_debug.context = ctx;
    s_bca_debug.f_debug = f_debug;
}

BCA_INT_IMPL void bca_debug_print(bca_u32_t level, const char* file,
                                  bca_u32_t line, const char* msg) {
    if (s_bca_debug.f_debug) {
        s_bca_debug.f_debug(s_bca_debug.context, level, file, line, msg);
    }
}

BCA_INT_IMPL void bca_debug(bca_u32_t level, const char* file, bca_u32_t line,
                            const char* fmt, ...) {
    va_list argp;
    char str[DEBUG_BUF_SIZE];
    int ret;

    if (!s_bca_debug.f_debug) {
        return;
    }

    va_start(argp, fmt);
#if defined(_WIN32)
#if defined(_TRUNCATE)
    ret = _vsnprintf_s(str, DEBUG_BUF_SIZE, _TRUNCATE, fmt, argp);
#else
    ret = _vsnprintf(str, DEBUG_BUF_SIZE, fmt, argp);

    if (ret < 0 || (bca_size_t) ret == DEBUG_BUF_SIZE) {
        str[DEBUG_BUF_SIZE - 1] = '\0';
        ret = -1;
    }

#endif
#else
    ret = vsnprintf(str, DEBUG_BUF_SIZE, fmt, argp);
#endif
    va_end(argp);

    if (ret >= 0) {
        if (ret > DEBUG_BUF_SIZE - 1) {
            ret = DEBUG_BUF_SIZE - 5;
            str[ret++] = '.';
            str[ret++] = '.';
            str[ret++] = '.';
        }

        str[ret++]     = '\n';
        str[ret] = '\0';
    }

    bca_debug_print(level, file, line, str);
}
